from tortoise import fields, signals
from .base import BaseModel, TimestampMixin
from .enums import AGVStatus
from random import randint


class AGV_car_Mo(BaseModel, TimestampMixin):
    agv_index = fields.IntField(unique=True, description="AGV编号")
    agv_type = fields.CharField(max_length=20, description="AGV类型")
    remote_host = fields.CharField(max_length=20, description="IP地址")
    local_port = fields.IntField(description="本机端口")
    remote_port = fields.IntField(description="远程端口")
    timeout = fields.IntField(default=3000, description="响应超时ms")
    timesend = fields.IntField(default=1000, description="发送间隔ms")
    isenable = fields.IntField(default=0, description="启用状态")

    class Meta:
        table = "agvs"
        unique_together = (("remote_host", "remote_port"),)


class AGV_realdata_Mo(BaseModel, TimestampMixin):
    """
    AGV实时数据模型
    存储AGV系统中每个AGV的实时数据，UDP通信实时数据。
    """
    car_id = fields.IntField(description="AGV_car_id")
    car_index = fields.IntField(description="agv_index_对应值")
    type = fields.CharField(max_length=20, description="读写类型")
    data = fields.CharField(max_length=500, null=True, description="实时数据")
    status = fields.CharField(max_length=20, null=True, description="数据状态")

    class Meta:
        table = "agv_realdata"
        unique_together = (("car_index", "type"),)


@signals.post_save(AGV_car_Mo)
async def sync_save_or_update(sender, instance, created, using_db=None, update_fields=None, **kwargs):
    """
    同步AGV_car_Mo实例到AGV_realdata_Mo表
    当AGV_car_Mo实例创建或更新时，同步创建或更新AGV_realdata_Mo表中对应的记录。
    """
    base_fields1 = {
        "updated_at": instance.updated_at,
        "car_id": instance.id,
        "car_index": instance.agv_index,
        "type": "W",
        "data": "",
        "status": "unknown",
    }

    base_fields2 = {
        "updated_at": instance.updated_at,
        "car_id": instance.id,
        "car_index": instance.agv_index,
        "type": "R",
        "data": "",
        "status": "unknown",
    }

    if created:
        await AGV_realdata_Mo.create(**base_fields1)
        await AGV_realdata_Mo.create(**base_fields2)
    else:
        print("carid" , instance.id)
        print("carindex" , instance.agv_index)
        await AGV_realdata_Mo.filter(car_id=instance.id, type="W").update(**base_fields1)
        await AGV_realdata_Mo.filter(car_id=instance.id, type="R").update(**base_fields2)

@signals.post_delete(AGV_car_Mo)
async def sync_delete(sender, instance, using_db=None, **kwargs):
    """
    同步删除AGV_car_Mo实例对应的AGV_realdata_Mo记录
    当AGV_car_Mo实例被删除时，同步删除AGV_realdata_Mo表中对应的记录。
    """
    await AGV_realdata_Mo.filter(car_index=instance.agv_index, type="W").delete()
    await AGV_realdata_Mo.filter(car_index=instance.agv_index, type="R").delete()


class AGV_position_Mo(BaseModel, TimestampMixin):
    """
    AGV实时位置模型
    存储AGV系统中每个AGV的实时位置数据，UDP通信实时位置数据。
    """
    car_index = fields.IntField(unique=True, description="agv_index_对应值")
    x = fields.IntField(null=True, description="x轴坐标")
    y = fields.IntField(null=True, description="y轴坐标")
    angle = fields.IntField(null=True, description="角度")
    speed = fields.IntField(null=True, description="速度")
    is_connected = fields.IntField(null=True, description="连接状态")
    status = fields.CharEnumField(AGVStatus, max_length=20, null=True, description="运行状态")
    battery = fields.IntField(null=True, description="电池电量")
    simulation = fields.IntField(null=True, description="虚拟设备")
    node_to_id = fields.ForeignKeyField("models.Map_Node_Mo", related_name="agvs_to", null=True, description="目标节点ID")
    next_node = fields.ForeignKeyField("models.Map_Node_Mo", related_name="node_next", null=True, description="下一个节点ID")
    current_node = fields.ForeignKeyField("models.Map_Node_Mo", related_name="node_current", null=True, description="当前节点ID")
    
    class Meta:
        table = "agv_position"
        table_description = "AGV实时位置表"

@signals.post_save(AGV_position_Mo)
async def sync_save_or_update(sender, instance, created, using_db=None, update_fields=None, **kwargs):
    if created:
        # 获取已保存实例的最新版本
        saved_instance = await AGV_position_Mo.get(car_index=instance.car_index)
        
        # 只更新非外键字段，避免外键处理错误
        await saved_instance.update_from_dict({
            "speed": randint(10, 25),
            "battery": randint(50, 100),
        })
        await saved_instance.save()
